package com.kwok.rbac.application.common.utils;

import com.alibaba.fastjson.JSON;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.kwok.rbac.application.common.constants.SystemUserTokenConstant;
import com.kwok.rbac.application.entity.SystemUserToken;
import com.kwok.rbac.application.exception.EmployeeTokenErrorException;
import com.kwok.rbac.application.exception.EmployeeTokenExpiredException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.Calendar;
import java.util.Map;
import java.util.Set;

//@Component将该类交给Spring容器管理，这样要用直接注入该对象即可
@Component
public class JWTUtil {

    @Value("${kwok.jwt.sign}")
    private String sign;

    public String generateToken(SystemUserToken systemUserToken) {
        //1.创建JWT实例
        JWTCreator.Builder builder = JWT.create();

        Calendar calendar = Calendar.getInstance();
        //设置过期时间为30min
        calendar.add(Calendar.MINUTE,30);

        //2.根据实例可以揉入数据
        //把systemUserToken转为JSON字符串（使用fastjson）
        builder.withClaim(SystemUserTokenConstant.JWT_SYSTEM_USER_TOKEN_KEY, JSON.toJSONString(systemUserToken));

        //给token设置过期时间
        builder.withExpiresAt(calendar.getTime());

        //3.根据签名生成token
        String token = builder.sign(Algorithm.HMAC256(sign));
        return token;
    }

    //校验token是否有效
    //校验成功返回true，校验失败返回false
    public SystemUserToken check(String token) {

        try {
            DecodedJWT decodedJWT = JWT.require(Algorithm.HMAC256(sign)).build().verify(token);
            String json = decodedJWT.getClaim(SystemUserTokenConstant.JWT_SYSTEM_USER_TOKEN_KEY).asString();
            return JSON.parseObject(json, SystemUserToken.class);
        } catch (TokenExpiredException e) {
            throw new EmployeeTokenExpiredException(1002,"token已过期");
        }catch (Exception e){
            throw new EmployeeTokenErrorException(1003,"token错误，校验失败");
        }
    }

}
